home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / applic / ntp / kent.shar / tblbuild.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-29  |  8.3 KB  |  281 lines

  1. #include <stdio.h>
  2.  
  3. /* tables to define S boxes and P, per NBS */
  4.  
  5. static int s_table [8] [4] [16] =
  6.     { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  7.       0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  8.       4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  9.       15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
  10.  
  11.       15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  12.       3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  13.       0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  14.       13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
  15.  
  16.       10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  17.       13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  18.       13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  19.       1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
  20.  
  21.       7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  22.       13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  23.       10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  24.       3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
  25.  
  26.       2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  27.       14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  28.       4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  29.       11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
  30.  
  31.       12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  32.       10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  33.       9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  34.       4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
  35.  
  36.       4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  37.       13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  38.       1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  39.       6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
  40.  
  41.       13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  42.       1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  43.       7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  44.       2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 };
  45.  
  46. static int ptab [32] =
  47.     { 16, 7, 20, 21,
  48.       29, 12, 28, 17,
  49.       1, 15, 23, 26,
  50.       5, 18, 31, 10,
  51.       2, 8, 24, 14,
  52.       32, 27, 3, 9,
  53.       19, 13, 30, 6,
  54.       22, 11, 4, 25 };
  55.  
  56. /* --- following is code to compute and store optimized tables --- */
  57. /*
  58.  
  59. The ip, ipi, and ipis tables, their use and generation... 
  60.  
  61. The IP table is used to perform the IP operations of DES
  62. efficiently, on a byte-by-byte basis.  There are 256 entries,
  63. each of which is 64 bits wide.  Each 64 bit entry is composed of
  64. two longs, and the [0]'th long contains the high order bits.) To
  65. do the IP transformation, one starts by extracting the rightmost
  66. byte from the block to be encrypted, and looking up the
  67. corresponding table entry.  Proceed by shifting the accumulated
  68. partial IP left one place and inclusive-OR'ing the table value
  69. for each more significant byte. Continue until all bytes
  70. have been processed. 
  71.  
  72. Regrettably, the structure of the IP-inverse operation is not
  73. such as to allow table lookup based on bytes selected in
  74. left-to-right (or right-to-left) order. To compensate for this
  75. fact, the ipis table is supplied. As one advances through the
  76. entries in ipis, one finds indexes which select the input byte
  77. (from 1-8, going left to right) whose value should be used to
  78. select the next entry in ipi. If this reordering is followed, the
  79. entries extracted from ipi can be inclusive-OR'd and left shifted
  80. (in the same manner described for ip), to perform the ip-inverse
  81. transformation. 
  82.  
  83. */
  84.  
  85. static long ip [2] [256];     
  86. static long ipi [2] [256];
  87. static int ipis [8] = {5, 1, 6, 2, 7, 3, 8, 4};
  88.  
  89. /* setipent -- given a byte value, compute the corresponding
  90.    entry and store it in the ip table. Computation based on
  91.    embedded knowledge of DES algorithm structure. */
  92.  
  93. setipent (val)  
  94. int     val;
  95. {
  96.   extern long ip [2] [256];
  97.  
  98.   ip [0] [val] = ip [1] [val] = 0L;
  99.  
  100.   if (val & 0X40) ip [0] [val] |= 0X1000000L;
  101.   if (val & 0X10) ip [0] [val] |= 0X10000L;
  102.   if (val & 0X4) ip [0] [val] |= 0X100L;
  103.   if (val & 0X1) ip [0] [val] |= 0X1L;
  104.   if (val & 0X80) ip [1] [val] |= 0X1000000L;
  105.   if (val & 0X20) ip [1] [val] |= 0X10000L;
  106.   if (val & 0X8) ip [1] [val] |= 0X100L;
  107.   if (val & 0X2) ip [1] [val] |= 0X1L;
  108. }
  109.  
  110. /* setipient -- given a byte value, compute the corresponding
  111.    entry and store it in the ipi table. Computation based on
  112.    embedded knowledge of DES algorithm structure. */
  113.  
  114. setipient (val)
  115. int     val;
  116. {
  117.   extern long ipi [2] [256];
  118.  
  119.   ipi [0] [val] = ipi [1] [val] = 0L;
  120.  
  121.   if (val & 0X1) ipi [0] [val] |= 0X1000000L;
  122.   if (val & 0X2) ipi [0] [val] |= 0X10000L;
  123.   if (val & 0X4) ipi [0] [val] |= 0X100L;
  124.   if (val & 0X8) ipi [0] [val] |= 0X1L;
  125.   if (val & 0X10) ipi [1] [val] |= 0X1000000L;
  126.   if (val & 0X20) ipi [1] [val] |= 0X10000L;
  127.   if (val & 0X40) ipi [1] [val] |= 0X100L;
  128.   if (val & 0X80) ipi [1] [val] |= 0X1L;
  129. }
  130.  
  131. /* setip -- initialize ip and ipi tables */
  132. setip ()        
  133. {
  134.   int i;
  135.  
  136.   for (i = 0; i < 256; i++) 
  137.   {
  138.     setipent (i);
  139.     setipient (i);
  140.   }
  141. }
  142.  
  143.  
  144. /* 
  145.  
  146. the snop table... its generation and use
  147.  
  148. Structure snop is a two-dimensional array.  The high-order
  149. dimension corresponds to 1 of 8 input bytes, each in the format
  150. produced by skedkeys and the E implementation (each byte has 6
  151. significant bits, left-justified in an 8-bit byte, and the input
  152. stream of bytes appears in 4 words as (1 3) (5 7) (2 4) (6 8).
  153. As the dimension varies from 0->7, bytes are selected from this
  154. ordering from left to right.
  155.  
  156. Using a series of 8 table lookups in snop (one for each byte),
  157. and IOR'ing the corresponding 32-bit entries, the caller can
  158. assemble the composition of s-box lookup and P permutation as
  159. specified in DES.  In a table entry corresponding to a particular
  160. byte, only those bits are set which correspond to those selected
  161. by P for the particular s-box.
  162.  
  163. The current format for snop has 64, not 256 entries per byte
  164. position.  Therefore, it is necessary to divide a byte's value by
  165. 4 before using it as a table index.
  166.  
  167. setsnop () computes the entries in snop, based on the NBS tables.
  168.  
  169. */
  170. static long snop [8] [64];
  171.  
  172.  
  173. setsnop ()
  174. {
  175.   extern long snop [8] [64];
  176.  
  177.   static int map_to_e [8] = {0, 2, 4, 6, 1, 3, 5, 7};
  178.   /* table used so that bytes ordered as produced by the
  179.    E algorithm implementation can be looked up left-to-right */
  180.  
  181.   int   i, j, ns, ni;
  182.   int   srow, scol;
  183.  
  184.   for (i = 0; i < 8; i++)
  185.   {
  186.     for (j = 0; j < 64; j++) snop [i] [j] = 0L;
  187.   }
  188.  
  189.   for (ns = 0; ns < 8; ns++)    /* do for each of 8 S-boxes */
  190.   {
  191.     for (ni = 0; ni < 64; ni++) /* do each entry in each box */
  192.     {
  193.       srow = ((ni & 32) >> 4) | (ni & 01);      /* lsb and msb of 6 bits */
  194.       scol = (ni >> 1) & 0XF;
  195.  
  196.       /* now, do successive left shifts on a snop entry,
  197.          IOR'ing in bits iff P selects a position from the S-box */
  198.  
  199.       for (i = 0; i < 32; i++)  /* over each bit in the entry */
  200.       {
  201.     if (map_to_e[ns] != ((ptab [i] - 1) / 4))
  202.     {
  203.       /* this bit not from this S-box: leave alone */
  204.       if (i != 31) snop [ns] [ni] <<= 1;
  205.       continue;
  206.     }
  207.     else
  208.     {
  209.       snop [ns] [ni] |=
  210.        (01 & (s_table [map_to_e[ns]] [srow] [scol] >> 
  211.             (3 - ((ptab [i] - 1) % 4))));
  212.       if (i != 31) snop [ns] [ni] <<= 1;
  213.     }
  214.       }
  215.     }
  216.   }
  217.  
  218. /*
  219.  for (i = 0; i < 8; i++)
  220.  {
  221.    for (j = 0; j < 64; j++)
  222.     printf ("snop [%d] [%d] = %lx\n", i, j, snop [i] [j]);
  223.  }
  224. */
  225.  
  226. }
  227.  
  228. /* main for tblbuild: compute and output ip, ipi, ipis, snop */
  229. main ()
  230. {
  231.   extern long ip [2] [256];     
  232.   extern long ipi [2] [256];
  233.   extern int ipis [8];
  234.   extern long snop [8] [64];
  235.   
  236.   int i, j;
  237.   FILE *fp, *fopen ();
  238.  
  239.   /* compute the static tables */
  240.   printf ("Computing transformation tables...\n");
  241.   setip ();
  242.   setsnop ();
  243.  
  244.   if (NULL == (fp = fopen ("ip", "w")))
  245.   {
  246.     printf ("tblbuild -- can't open output file 'ip'\n");
  247.     exit (1);
  248.   }
  249.   for (i = 0; i < 2; i++)
  250.     for (j = 0; j < 256; j++) fprintf (fp, "%lx\n", ip [i] [j]);
  251.   fclose (fp);
  252.  
  253.   if (NULL == (fp = fopen ("ipi", "w")))
  254.   {
  255.     printf ("tblbuild -- can't open output file 'ipi'\n");
  256.     exit (1);
  257.   }
  258.   for (i = 0; i < 2; i++)
  259.     for (j = 0; j < 256; j++) fprintf (fp, "%lx\n", ipi [i] [j]);
  260.   fclose (fp);
  261.  
  262.   if (NULL == (fp = fopen ("ipis", "w")))
  263.   {
  264.     printf ("tblbuild -- can't open output file 'ipis'\n");
  265.     exit (1);
  266.   }
  267.   for (i = 0; i < 8; i++) fprintf (fp, "%x\n", ipis [i]);
  268.   fclose (fp);
  269.  
  270.   if (NULL == (fp = fopen ("snop", "w")))
  271.   {
  272.     printf ("tblbuild -- can't open output file 'snop'\n");
  273.     exit (1);
  274.   }
  275.   for (i = 0; i < 8; i++)
  276.     for (j = 0; j < 64; j++) fprintf (fp, "%lx\n", snop [i] [j]);
  277.   fclose (fp);
  278.  
  279.   printf ("tblbuild -- table files output\n");
  280. }
  281.